<?php
class ReportsController extends AppController {

	var $name = 'Reports';
	var $uses = array('Order','Customer','Employee','TypeOfWork');

	var $permissions = array(
		'index' => array('admin','manag','emplo'),
		'generate' => array('admin','manag','emplo')
	);
	
	var $raport = array();
	var $time;
		
	var $definde_reports = array();
	
	public function beforeFilter(){
		parent::beforeFilter();
		$this->definde_reports = array(
			'2_any_orders_by_order'	=> __("Wykaz zlecen za wybrany okres wg miejsca realizacji",true),
			'1_any_orders_by_date'	=> __("Wykaz zlecen za wybrany okres wg daty realizacji",true)
//			,			
//			'3_one_order'			=> __("Wykaz pracownikow w jednym zleceniu za wybrany okres.",true),
//			'4_many_orders'			=> __("Wykaz pracownikow w wybranych zleceniach za wybrany okres.",true),	
//			'5_one_employee' 		=> __("Wykaz zlecen dla jednego pracownika za wybrany okres.",true),
//			'6_many_employees'		=> __("Wykaz zlecen dla wybranych pracownikow za wybrany okres.",true)			
		);	
		
		$typeOfWorks = $this->Employee->TypeOfWork->find('list');
		$this->set(compact('typeOfWorks'));
		$this->set('definde_reports',$this->definde_reports);
		
		App::import('Helper','time'); 
		$this->time = new TimeHelper();
		
		App::import('Controller','orders'); 
		$this->set(OrdersController::dictionaries());
	}	
	
	public function index(){
		
	}
	
	public function generate(){
		if (!empty($this->data) 
			&& isset($this->data['Reports']['date_from']) && !empty($this->data['Reports']['date_from'])
			&& isset($this->data['Reports']['date_to']) && !empty($this->data['Reports']['date_to'])
		){
			
			$orders_month = $this->Order->find('all',array('conditions'=>array(
				'OrdersCycle.type_of_cycle_id' => '1'
			)));
			$orders_week = $this->Order->find('all',array('conditions'=>array(
				'OrdersCycle.type_of_cycle_id' => '2'
			)));
			$orders_daily = $this->Order->find('all',array('conditions'=>array(
				'OrdersCycle.type_of_cycle_id' => '3'
			)));	
			$orders_once = $this->Order->find('all',array('conditions'=>array(
				'OrdersCycle.type_of_cycle_id' => '4'
			)));
			
			$this->_monthly($orders_month);
			$this->_weekly($orders_week);
			$this->_daily($orders_daily);
			$this->_once($orders_once);
			ksort($this->raport);
			$this->Session->write('Reports.raport',$this->raport);	
			$this->Session->write('Reports.report_type',$this->data['Reports']['report_type']);
			$this->Session->write('Reports.date_from',$this->data['Reports']['date_from']);
			$this->Session->write('Reports.date_to',$this->data['Reports']['date_to']);
			$this->set('orders',$this->raport);
			
			// view o nazwie typu raportu
			$this->autoRender = false;
			$this->render($this->data['Reports']['report_type']);
			
		}else{
			$this->Session->setFlash(__("Please specify print parameters", true));	
			$this->redirect(array('action'=>'index'));
		}		
	}
	
	public function printPdf(){
		$this->raport = $this->Session->read('Reports.raport');	
		if(is_array($this->raport)){	
			$this->set('orders',$this->raport);
			$this->layout = 'pdf';
			// view o nazwie typu raportu
			$this->autoRender = false;
			$this->render($this->Session->read('Reports.report_type')."_pdf");
		}else{
			$this->redirect(array('action'=>'index'));
		}		
	}
	
	
	private function _monthly($orders_month){

		$date_start = $this->EuroDate->convert($this->data['Reports']['date_from'],"Y-m-d");
		$date_end = $this->EuroDate->convert($this->data['Reports']['date_to'],"Y-m-d");
					
		// for every orders check day
		foreach ($orders_month as $key => $order) {
			$miesiace = $this->_oblicz_miesiace($order['OrdersCycle']['date_start'],$date_end,$order['OrdersCycle']['repeat'] );
			$date_start__ = explode("-",$date_start);		
			$date_progres = new DateTime();
			$date_progres->setDate($date_start__[0], $date_start__[1], $date_start__[2]);
			
			$date_order_start = $this->time->format('Y-m-d',$order['OrdersCycle']['date_start']);
			$date_order_end = (!empty($order['OrdersCycle']['date_end'])) ? $this->time->format('Y-m-d',$order['OrdersCycle']['date_end']) : $date_end;
			
					
			while ($date_progres->format("Y-m-d") <= $date_end ) {	
							
				$day = $date_progres->format("j");
				$month = $date_progres->format("m");
				$year = $date_progres->format("Y");	
				if(
					$date_order_start <= $date_progres->format("Y-m-d")
					&& $date_order_end >= $date_progres->format("Y-m-d") 
					&& $order['OrdersCycle']['_'.$day] == 1
					&& array_key_exists($month.$year, $miesiace)
				){	
		
					$this->_save_array_report($date_progres->format("Y-m-d"),$order);

				}
				$date_progres->modify("+1 day");
			}						
		}	
	}
	
	private function _weekly($orders_week){

		$date_start = $this->EuroDate->convert($this->data['Reports']['date_from'],"Y-m-d");
		$date_end = $this->EuroDate->convert($this->data['Reports']['date_to'],"Y-m-d");
				
		// for every orders check day
		foreach ($orders_week as $key => $order) {
			$weeks = $this->_oblicz_tygodnie($order['OrdersCycle']['date_start'],$date_end,$order['OrdersCycle']['repeat'] );
			$date_start__ = explode("-",$date_start);		
			$date_progres = new DateTime();
			$date_progres->setDate($date_start__[0], $date_start__[1], $date_start__[2]);
			
			$date_order_start = $this->time->format('Y-m-d',$order['OrdersCycle']['date_start']);
			$date_order_end = (!empty($order['OrdersCycle']['date_end'])) ? $this->time->format('Y-m-d',$order['OrdersCycle']['date_end']) : $date_end;
					
			while ($date_progres->format("Y-m-d") <= $date_end ) {	

				$nDay = $date_progres->format("N");
				$nWeek =$date_progres->format('W');

				if(
					$date_progres->format("Y-m-d") >= $date_order_start 
					&& $date_progres->format("Y-m-d") <= $date_order_end 
					&& $order['OrdersCycle']['_'.$nDay] == 1
					&& array_key_exists($nWeek, $weeks)
				){	
					$this->_save_array_report($date_progres->format("Y-m-d"),$order);
				}
				$date_progres->modify("+1 day");
			}						
		}	
	}	
	
	private function _daily($orders_daily){
		$date_start = $this->EuroDate->convert($this->data['Reports']['date_from'],"Y-m-d");
		$date_end = $this->EuroDate->convert($this->data['Reports']['date_to'],"Y-m-d");
					
		// for every orders check day
		foreach ($orders_daily as $key => $order) {
			$dni = $this->_oblicz_dni($order['OrdersCycle']['date_start'],$date_end,$order['OrdersCycle']['repeat'] );
			$date_start__ = explode("-",$date_start);		
			$date_progres = new DateTime();
			$date_progres->setDate($date_start__[0], $date_start__[1], $date_start__[2]);

			$date_order_start = $this->time->format('Y-m-d',$order['OrdersCycle']['date_start']);			
			$date_order_end = (!empty($order['OrdersCycle']['date_end'])) ? $this->time->format('Y-m-d',$order['OrdersCycle']['date_end']) : $date_end;
			
			while ($date_progres->format("Y-m-d") <= $date_end ) {	
							
				$_day = $date_progres->format("j");
				$keyDay = $date_progres->format("dmY");
				
				if(
					$date_order_start <= $date_progres->format("Y-m-d")
					&& $date_order_end >= $date_progres->format("Y-m-d")
					&& array_key_exists($keyDay, $dni)
				){	
		
					$this->_save_array_report($date_progres->format("Y-m-d"),$order);
				}
				$date_progres->modify("+1 day");
			}						
		}		
	}
	
	private function _once($orders_once){
		if(is_array($orders_once) && !empty($orders_once)){

			
			$date_start = $this->EuroDate->convert($this->data['Reports']['date_from'],"Y-m-d");
			$date_end = $this->EuroDate->convert($this->data['Reports']['date_to'],"Y-m-d");
						
			
			// for every orders check day
			foreach ($orders_once as $key => $order) {
				$date_order = $this->time->format('Y-m-d',$order['OrdersCycle']['date_start']);
				
				if( $date_order >= $date_start && $date_order <= $date_end){
					$this->_save_array_report($date_order,$order);
				}									
			}	
		}	
	}	
	
	private function _save_array_report($date_progres,$order){
		switch ($this->data['Reports']['report_type']){
			case '1_any_orders_by_date':
				foreach ($order['Employee'] as $key => $employee) {						
					// dodajemy dzien i dane zlecenia
					$this->raport[$date_progres][$employee['id']]['emplo'] = $employee;
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['Order'] = $order['Order'];
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['Customer'] = $order['Customer'];
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['TypeOfService'] = $order['TypeOfService'];
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['TypesOfSpaces'] = $order['TypesOfSpaces'];
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['OrdersCycle'] = $order['OrdersCycle'];
					$this->raport[$date_progres][$employee['id']]['orders'][$order['Order']['id']]['OrdersEmployee'] = $employee['OrdersEmployee'];						
				}
				break;
			case '2_any_orders_by_order':
				foreach ($order['Employee'] as $key => $employee) {						
					// dodajemy dzien i dane zlecenia
					$this->raport[$order['Order']['id']]['Employees'][$employee['id']] = $employee;
					$this->raport[$order['Order']['id']]['Order'] = $order['Order'];
					$this->raport[$order['Order']['id']]['Customer'] = $order['Customer'];
					$this->raport[$order['Order']['id']]['TypeOfService'] = $order['TypeOfService'];
					$this->raport[$order['Order']['id']]['TypesOfSpaces'] = $order['TypesOfSpaces'];	
					$this->raport[$order['Order']['id']]['OrdersCycle'] = $order['OrdersCycle'];
					$this->raport[$order['Order']['id']]['Terms'][$date_progres] = $date_progres ;	
				}
				break;
		}
	}
	
	/**
	 * 
	 * Oblicza miesiące w ktorych maja byc 
	 * obliczone zlecenia do raportu
	 * 
	 * @param date $from
	 * @param date $to
	 * @param numeric $repeat
	 */
	private function _oblicz_miesiace($from, $to, $repeat=1){
		$repeat = (empty($repeat)) ? 1 :$repeat ;
		$dStart = new DateTime();
		$from_ = explode("-",$from);
		$dStart->setDate($from_[0], $from_[1], $from_[2]);
		$miesiace = array();
		while ($dStart->format("Y-m-d") <= $to) {
			$miesiace[$dStart->format("mY")]= $dStart->format("Y-m-d");
			$dStart->modify("+{$repeat} month");
		}
		return $miesiace;
	}
	
	private function _oblicz_tygodnie($from, $to, $repeat=1){
		$repeat = (empty($repeat)) ? 1 :$repeat ;
		
		$week_start = $this->time->format('W',$from);
		$week_end = $this->time->format('W',$to);		
		$weeks = array();
		while ($week_start <= $week_end ) {
			$weeks[$week_start] = $week_start;
			$week_start = $week_start + $repeat;
		}
		return $weeks;
	}	
	
	private function _oblicz_dni($from, $to, $repeat=1){
		$repeat = (empty($repeat)) ? 1 :$repeat ;
		$dStart = new DateTime();
		$from_ = explode("-",$from);
		$dStart->setDate($from_[0], $from_[1], $from_[2]);
		$dni = array();
		while ($dStart->format("Y-m-d") <= $to) {
			$dni[$dStart->format("dmY")] = $dStart->format("Y-m-d");
			$dStart->modify("+{$repeat} day");
		}
		return $dni;
	}	

}
?>